package service4gateway

import (
	"MyBlogv2/blog-common/HttpCode"
	"MyBlogv2/blog-common/models"
	"MyBlogv2/blog-common/response"
	"github.com/gin-gonic/gin"
	"strconv"
)

func GetMenuList(c *gin.Context) {
	userIdValue, _ := c.Get("userId")
	userId, _ := userIdValue.(int)
	typeId, _ := strconv.Atoi(c.Param("typeId"))
	menuList := getMenuList(typeId, "", -1, userId)
	response.ResponseOK(c, menuList)
	return

}

func GetMenuListByTypeId(c *gin.Context) {
	//typeId, _ := strconv.Atoi(c.Param("typeId"))
	var menuList []models.MenuVo
	models.Db.Model(new(models.MenuVo)).Find(&menuList)
	response.ResponseOK(c, menuList)
	return
}

func SearchMenu(c *gin.Context) {
	userIdValue, _ := c.Get("userId")
	userId, _ := userIdValue.(int)
	username := c.Query("username")
	status, _ := strconv.Atoi(c.Query("status"))
	typeId, _ := strconv.Atoi(c.Param("typeId"))
	menuList := getMenuList(typeId, username, status, userId)
	response.ResponseOK(c, menuList)
	return

}

func getMenuList(typeId int, username string, status int, userId int) []models.MenuVo {
	menuList := make([]models.MenuVo, 0)
	if typeId == 0 {
		var roleIds []int
		models.Db.Model(new(models.UserRole)).Select("role_id").Where("user_id = ?", userId).Find(&roleIds)
		var menuIds []int
		models.Db.Model(new(models.RoleMenu)).Select("menu_id").Where("role_id in (?)", roleIds).Find(&menuIds)
		var allMenuIds []int
		models.Db.Model(new(models.Menu)).Select("id").Find(&allMenuIds)
		var allRoleMenuIds []int
		models.Db.Model(new(models.RoleMenu)).Select("id").Find(&allRoleMenuIds)
		// 创建一个 map 来存储 allRoleMenuIds 中的值
		roleMenuMap := make(map[int]bool)
		for _, id := range allRoleMenuIds {
			roleMenuMap[id] = true
		}
		// 遍历 allMenuIds，找出不在 allRoleMenuIds 中的元素
		var diffMenuIds []int
		for _, id := range allMenuIds {
			if !roleMenuMap[id] {
				diffMenuIds = append(diffMenuIds, id)
			}
		}
		menuIds = append(menuIds, diffMenuIds...)
		models.Db.Model(new(models.MenuVo)).Where("id in (?)", menuIds).Find(&menuList)

	}
	if typeId == 1 && (username != "" || status != -1) {
		db := models.Db.Model(new(models.MenuVo))
		if username != "" {
			db.Where("menu_name like ?", "%"+username+"%")
		}
		if status != -1 {
			db.Where("status = ?", status)
		}
		db.Find(&menuList)
	}

	return menuList
}

func GetAllRole(c *gin.Context) {
	var roleVoList []models.RoleVo
	models.Db.Model(new(models.RoleVo)).
		Where("status = ?", 0).
		Find(&roleVoList)
	response.ResponseOK(c, roleVoList)

}

func AddMenu(c *gin.Context) {
	var menuDto models.MenuDto
	if err := c.ShouldBindJSON(&menuDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
		return
	}
	switch menuDto.RouterType {
	case 0:
		if menuDto.Component == "" {
			menuDto.Component = "RouteView"
		}
	case 1:
		menuDto.Component = "Iframe"
	case 2:
		menuDto.Component = ""

	}
	models.Db.Model(new(models.MenuDto)).Create(&menuDto)
	for _, v := range menuDto.RoleId {
		var roleMenu models.RoleMenu
		roleMenu.RoleId = v
		roleMenu.MenuId = menuDto.Id
		models.Db.Model(new(models.RoleMenu)).Create(&roleMenu)
	}
	response.ResponseOK(c, nil)
}

func GetMenuById(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	var roleIds []int
	models.Db.Model(new(models.RoleMenu)).Select("role_id").Where("menu_id = ?", id).Find(&roleIds)
	var menu models.MenuByIdVo
	models.Db.Model(new(models.MenuVo)).Where("id = ?", id).Find(&menu)
	menu.RoleId = roleIds
	if menu.Component == "" {
		menu.RouterType = 2
	} else if menu.Component == "Iframe" {
		menu.RouterType = 1
	} else {
		menu.RouterType = 0
	}
	response.ResponseOK(c, menu)
	return
}

func UpdateMenu(c *gin.Context) {
	var menuDto models.MenuDto
	if err := c.ShouldBindJSON(&menuDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
		return
	}
	db := models.Db.Model(new(models.MenuDto)).Where("id = ?", menuDto.Id)
	db.Updates(menuDto)
	if menuDto.RouterType == 3 {
		menuDto.Component = "RouteView"
	}
	if menuDto.RouterType == 0 {
		db.Update("redirect", nil)
	}
	if menuDto.RouterType == 0 || menuDto.RouterType == 3 {
		db.Update("url", nil)
	}
	if menuDto.RouterType == 1 {
		menuDto.Component = "Iframe"
		db.Update("target", nil)
	}
	if menuDto.RouterType == 2 {
		db.Update("component", nil)
		db.Update("redirect", nil)
	}
	if menuDto.ParentId == 0 {
		db.Update("parent_id", nil)
	}
	var count int64
	models.Db.Model(new(models.RoleMenu)).Where("menu_id = ?", menuDto.Id).Count(&count)
	if count > 0 {
		sql := "delete from role_menu where menu_id = ?"
		models.Db.Exec(sql, menuDto.Id)
	}
	if len(menuDto.RoleId) > 0 {
		for _, v := range menuDto.RoleId {
			var roleMenu models.RoleMenu
			roleMenu.RoleId = v
			roleMenu.MenuId = menuDto.Id
			models.Db.Model(new(models.RoleMenu)).Create(&roleMenu)
		}
	}
	response.ResponseOK(c, nil)
	return
}

func DeleteMenu(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	var count int64
	models.Db.Model(new(models.Menu)).Where("parent_id = ?", id).Count(&count)
	if count > 0 {
		response.ResponseError(c, HttpCode.NO_DELETE_CHILD_MENU)
		return
	}
	models.Db.Model(new(models.Menu)).Where("id = ?", id).Delete(new(models.Menu))
	models.Db.Model(new(models.RoleMenu)).Where("menu_id = ?", id).Delete(new(models.RoleMenu))
	models.Db.Model(new(models.Permission)).Where("menu_id = ?", id).Delete(new(models.Permission))
	response.ResponseOK(c, nil)
	return

}
